﻿#include "FileUtils.h"
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QStorageInfo>

FileUtils::FileUtils()
{

}

QString FileUtils::CreateDirFromDatetime(QString baseFloder, QDateTime dt)
{
    QString folder=baseFloder+"//"+dt.toString("yyyy-MM-dd_hh-mm-ss");
    QDir dir;
    if(dir.mkdir(folder))
    {
        return folder;
    }
    else
    {
        return "";
    }
}

bool FileUtils::TryCreateDir(QString folder)
{
    QDir dir(folder);
    if(!dir.exists())
    {
        dir.mkdir(dir.absolutePath());
    }
    return true;
}

bool FileUtils::ExportToCsv(QMap<QString, QList<double> > data, QString fileName)
{
    if(data.keys().count()==0||(data.keys().count()!=0&&data.first().count()==0))
    {
        qDebug()<<"data is empty!";
        return false;
    }

    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug()<<"open file fail";
        return false;
    }

    QTextStream out(&file);

    int col=data.count();
    int row=data.first().count();
    //写表头
    for(int i = 0;i < col; i++)
    {
        out<<data.keys().at(i);
        QString end=(i==(col-1))?"\n":",";;
        out<<end;
    }
    //写数据
    for(int i = 0;i < row; i++)
    {
        for(int j = 0;j < col; j++)
        {
            data[data.keys().at(j)].at(i);
            out<<data[data.keys().at(j)].at(i);
            QString end=(j==(col-1))?"\n":",";;
            out<<end;
        }
    }
    file.close();

    return true;
}

bool FileUtils::ExportToCsv(QList<QList<QString>> data, QString fileName)
{
    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug()<<"open file fail";
        return false;
    }

    QTextStream out(&file);

    //写数据
    int row=data.count();
    int col=data.first().count();
    for(int i = 0;i < row; i++)
    {
        for(int j = 0;j < col; j++)
        {
            out<<data.at(i).at(j);
            QString end=(j==(col-1))?"\n":",";;
            out<<end;
        }
    }
    file.close();

    return true;
}


QList<QList<QString>> FileUtils::ReadCsvFile(const QString &filePath)
{
    QList<QList<QString>> data;

    QFile file(filePath);
    if (!file.exists()||!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        // 文件打开失败，可以在此处添加适当的错误处理逻辑
        throw QString("未找到该文件%1").arg(filePath);
    }

    QTextStream in(&file);
    while (!in.atEnd())
    {
        QString line = in.readLine();
        QList<QString> row = line.split(',').toVector().toList();

        QList<QString> trimRow;
        for(QString item:row)
        {
            trimRow.append(item.trimmed());
        }
        data.append(trimRow);
    }

    file.close();
    return data;
}

// 函数用于计算矩阵的转置
QList<QList<QString>> FileUtils::TransposeMatrix(const QList<QList<QString>>& mat)
{
    int numRows = mat.size();
    int numCols = mat.first().count();

    QList<QList<QString>> ret;

    for (int i = 0; i < numCols; ++i) {
        QList<QString> row;
        for (int j = 0; j < numRows; ++j) {
            row.append(mat[j][i]);
        }
        ret.append(row);
    }

    return ret;
}

QList<QString> FileUtils::listFilesRecursively(const QDir &dir) {
    QList<QString> fileList;

    QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);

    foreach (const QFileInfo &fileInfo, fileInfoList) {
        fileList.append(fileInfo.filePath());
    }

    QStringList subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    foreach (const QString &subDirName, subDirs) {
        QDir subDir(dir.absoluteFilePath(subDirName));
        QList<QString> subDirFiles = listFilesRecursively(subDir);
        fileList.append(subDirFiles);
    }

    return fileList;
}

QList<QString> FileUtils::Filter(QList<QString> fileNames, QDateTime start, QDateTime end)
{
    QList<QString> ret;
    foreach (const QString &fileName, fileNames) {
        QFileInfo fileInfo(fileName);
        QDateTime fileDateTime = fileInfo.lastModified(); // 或使用fileInfo.created()获取创建时间
        if (fileDateTime >= start& fileDateTime <= end) {
            ret.append(fileName);
        }
    }
    return ret;
}

QString FileUtils::ReadFile(QString fn)
{
    QFile file(fn);
    file.open(QFile::ReadOnly|QIODevice::Text);
    QString styleSheet = file.readAll();
    return styleSheet;
}

void FileUtils::ExportToFile(QString content, QString fn)
{
    QFile file(fn);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "Cannot open file for writing:" << file.errorString();
        return;
    }

    QTextStream out(&file);
    out.setCodec("utf-8");    out << content;
    file.close();
}


QList<QString> FileUtils::Filter(QList<QString> fileNames, QString filter)
{
    QList<QString> ret;
    for(auto f:fileNames)
    {
        if(f.contains(filter))
        {
            ret.append(f);
        }
    }
    return ret;
}

QList<QString> FileUtils::listFilesRecursively(const QDir &dir, QString filter)
{
    QList<QString> files=listFilesRecursively(dir);
    QList<QString> ret;
    for(auto f:files)
    {
        if(f.endsWith(filter))
        {
            ret.append(f);
        }
    }
    return ret;
}

QList<QString> FileUtils::ListFiles(const QDir &dir, QString filter)
{
    QList<QString> fileList;
    QStringList nameFilters;
    nameFilters << filter;
    QFileInfoList fileInfoList = dir.entryInfoList(nameFilters,QDir::Files);
    foreach (const QFileInfo &fileInfo, fileInfoList) {
        fileList.append(fileInfo.filePath());
    }
    return fileList;
}

void FileUtils::CopyFileZZZ(const QString &sourceFilePath, const QString &destinationFilePath)
{
    // 创建源文件对象
        QFile sourceFile(sourceFilePath);

        // 判断源文件是否存在
        if (!sourceFile.exists()) {
            return;
        }

        // 创建目标文件对象
        QFile destinationFile(destinationFilePath);
        // 如果目标文件存在，则删除
        if (destinationFile.exists()) {
            if (!destinationFile.remove()) {
                qDebug() << "Failed to remove existing destination file: " << destinationFilePath;
                return;
            }
        }

        QFile::copy(sourceFilePath,destinationFilePath);
        // 关闭文件
//        sourceFile.close();
//        destinationFile.close();
}

void FileUtils::ClearFile(QString dir, int remainGB)
{
    if(GetRemainGB(dir)<remainGB)
    {
        return;
    }

    QDir directory(dir);
    if(directory.exists())
    {
        QStringList folders=directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
        QStringList absolutePaths;
        foreach (const QString &folder, folders) {
            QString absolutePath = directory.absoluteFilePath(folder);
            absolutePaths.append(absolutePath);
        }
        // 按照创建时间排序
        std::sort(absolutePaths.begin(), absolutePaths.end(), [](QString folder1,QString folder2){
            QFileInfo fileInfo1(folder1);
            QFileInfo fileInfo2(folder2);
            return fileInfo1.created()>fileInfo2.created();
        });
        for(QString folderItem:absolutePaths)
        {
            if(GetRemainGB(dir)>remainGB)
            {
                break;
            }
            qDebug()<<__FUNCTION__<<__LINE__<<"remove "<<folderItem<<QDir(folderItem).removeRecursively();
        }
    }
}

int FileUtils::GetRemainGB(QString dir)
{
    // 获取目录所在磁盘的可用空间
    QStorageInfo storageInfo(dir);
    qint64 availableDiskSpace = storageInfo.bytesAvailable();
    return availableDiskSpace/(1024*1024*1024);
}

